# -*- coding: utf-8 -*-
#! /home/slam-dunk/anaconda3/envs/ros/bin/python
import numpy
import numpy as np
import matplotlib.pyplot as plt

def show(x1,x2):
    for i in range(x1.shape[0]-1):
        if y[i]==1:
            plt.plot(x1[i],x2[i],'+')
        else:
            plt.plot(x1[i],x2[i],'o')


def newton(x:np.ndarray,y:np.ndarray)->np.ndarray:
    '''
    :param x:17*3
    :param y:17*1
    :return:w,3*1
    '''
    w=np.ones(x.shape[1])
    for i in range(100):
        #17*1
        t=np.dot(x,w[:,np.newaxis])
        z=np.exp(t)/(np.exp(t)+1)
        #3*1
        zhi:np.ndarray=np.dot(x.T,z)-np.dot(x.T,y[:,np.newaxis])
        tmp1=np.exp(t)+1
        tmp1=np.square(tmp1)
        tmp2=np.exp(t)
        #17*1
        tmp=tmp2/tmp1
        #
        haisheng=np.dot(x.T,tmp*x)
        w=w-np.linalg.inv(haisheng).dot(zhi).reshape(-1)
    print(w)
    return w

def gradDescent(x:np.ndarray,w:np.ndarray,y:np.ndarray)->np.ndarray:
    '''
    param:
    :return:cend orientation
    '''
    global line
    for i in range(500):
        t=np.dot(x,w[:,np.newaxis])
        z=np.exp(t)/(np.exp(t)+1)
        newflag=np.dot(x.T,z)-np.dot(x.T,y[:,np.newaxis])
        w-=line*newflag.reshape(3)
    return w
x1=[]#midu
x2=[]#tiandu
y=[]
with open('3.3.txt',mode='r') as file:
    for line in file:
        data=line.split(',')
        x1.append(float(data[1]))
        x2.append(float(data[2]))
        y.append(float(data[3]))
x1=np.array(x1)
x2=np.array(x2)
y=np.array(y)
x3=np.ones_like(x1)
x=np.concatenate((x1[:,np.newaxis],x2[:,np.newaxis]),axis=1)
x=np.concatenate((x,x3[:,np.newaxis]),axis=1)
show(x1,x2)
W=np.ones(x.shape[1])*0.1#e weights data
line=0.05
W=gradDescent(x,W,y)
print(W)
w_newton=newton(x,y)
#correct rate
predect=np.dot(x,W)
predect[predect>0]=1
predect[predect<=0]=0
corrct_rate=np.logical_xor(predect,y)
corrct_rate=np.logical_not(corrct_rate).sum()
print(f'corrct_rate={corrct_rate/y.shape[0]}')
#plot logister line
left=-(W[2]+W[0]*0.1)/W[1]
right=-(W[2]+W[0]*0.9)/W[1]
plt.plot([0.1,0.9],[left,right],'y-')

left=-(w_newton[2]+w_newton[0]*0.1)/w_newton[1]
right=-(w_newton[2]+w_newton[0]*0.9)/w_newton[1]
plt.plot([0.1,0.9],[left,right],'r-')
plt.show()
